Lesson
7: Starting a Spell in JASS
Overview
Welcome to the next
lesson. The basics have pretty much been covered, and now you'll
probably want to use JASS to create spells or something. In this
lesson, we'll go through the process of making a spell similar to the
Omnislash spell found in DotA. (I've never actually seen the spell,
but I know somewhat of how it works) This will show you some basic
things used in JASS and room will be left for you to be able to
modify the spell later on.
Starting
Off
Before making a
spell, you'll have to consider how it will work, what is happening
step by step. First off, we need the trigger to go off when a unit
casts a certain spell, right? And then we can begin thinking of the
actions. In the spell I'm thinking off, the hero moves around in an
area hitting a certain amount of units, but never the same unit
twice. If you're looking at the spell being cast in-game, it might
seem confusing, it might not. You have to break things down little by
little. Here's some code for now that will start us off and I'll add
to it as the lesson progresses:
So far all we have is the basic
trigger set up that will go off whenever the right ability is cast.
You need to make sure you've created an ability (preferably based off
channel with the values set correctly, if you need to know more about
channel, please ask). Now we will create the actual effects of the
spell. Now you'll need to think "what happens in the spell".
Here's what happens: the hero is moved around within a certain area,
he will only be moved to enemies, for each unit he is moved to, he
will deal damage, and at the end he will return to the spot that he
started at. The first thing to do now is to create a local variable
to everything we'll need to keep track of. Here's what I thought of:
a unit variable for the hero, a location for where the hero starts
at, a group to hold all the enemies the hero will hit, and another
unit variable to temporarily hold picked units in. You might not get
the point of the last variable, but I'll show you how it's used soon.
Here's what we should have now:
Now, if you've used GUI before,
you'll probably be wanting to do something like "Pick Every Unit
in (group) and do actions", but there's a problem with that. In
order to use that function (it's know as ForGroup in JASS), you'll
need a separate function that you'll be unable to pass any values to.
Now you could use global variables to transfer information, but then
the spell wouldn't be able to be used by more than 1 unit at a time.
You could possibly think of other ways around this, but they'd take
more time than it would be worth. I'll give you a hint on how I do
it, I use a loop. "Loop?" you might be thinking, "how
can I use a loop?" because if you've used GUI before, the loops
would run for a fixed length (for integer # through #, do actions),
unlike in JASS where a loop will only end when a certain condition is
met. And that condition will be that all enemies in the enemy group
have been hit. Here's some more code to hopefully explain a little
bit more of what I mean:
In this section of code, we've
set up some more basic parts to our code. We've initialized the
variables and then filled the group with units within 500 range of
the caster. Next, we start a loop and for each cycle in the loop, the
temporary unit variable will be set to a unit from the group. Then
we'll tell the loop to exit when the group has no units left in it or
the caster has hit 5 enemies (count would be decreased for each enemy
hit). At the end of each loop, the unit being used will be removed
from the group so that it can't be picked again (and so prevents an
infinite loop as well). Then we end the code executed by the loop and
end the function.
The next step will now be to add
in what the function will do for each unit picked. The first thing
that you will have to notice is that the GroupEnumUnitsInRangeOfLoc
grouped all units in 500 range of the hero's location, including
allies and the hero. That means we'll have to add a simple condition
to check whether or not the unit is an ally before performing
additional actions. After that's done, what next? The unit will have
to move to each enemy hit and damage them, right? Don't forget
setting the count variable to count – 1 as well, or more
enemies could be hit than desired. Before going on to the next bit of
code, declare another location variable to hold the picked enemy's
position, I'll go by the name of temp_loc. Here's what we'll have
next for the loop
loop |
Okay, this loop will now allow our
unit to move to every unit within range and damage them. You might
think we're done, right? Our hero will move to each unit in range and
damage them, but you now have to ask yourself if we're missing
anything. Are we?
Challenge
I bet you've already guessed the
challenge, finish the spell! Don't worry about special effects
(unless you want to), you just need to finish up on the basics that
will happen and clean memory leaks. In the next lesson, the spell
will be finished up and enhanced with special effects and more! Don't
hesitate to post code on the forums if you're having trouble.
Good
Luck! -wyrmlord